<script lang="ts">
	import { onMount, tick } from 'svelte';
	import Portal from 'svelte-portal';
	import PopoverSlot from './PopoverSlot.svelte';
	import Scrollbar from '$lib/components/Basic/Scrollbar/Scrollbar.svelte';
	import type { Option } from '$lib/components/Basic/Popover/types';
	import { getElementRelativePos } from '$lib/utils/position/getElementPos';
	import { ensurePortalContainer } from '$lib/utils/container/ensurePortalContainer';
	import { type Placement } from './types';

	// 组件属性
	export let placement: Placement = 'auto';
	export let label: string = 'label';
	export let options: Option[] | undefined;
	export let triggerRef: HTMLElement;
	let triggerRect: {
		top: number;
		left: number;
		bottom: number;
		right: number;
		width: number;
		height: number;
	} = {
		top: 0,
		left: 0,
		bottom: 0,
		right: 0,
		width: 0,
		height: 0
	};
	let cascaderRef: HTMLElement; // 弹出框引用
	let popoverSlotRefs: HTMLElement[] = [];
	let portalContainer: HTMLElement | undefined;
	let localIdCounter = 0;

	// 事件回调 - Svelte 5 中使用回调函数替代 createEventDispatcher
	export let onClose: () => void = () => {};
	export let onChange: (option: Option) => void = () => {};

	//申明一个二位数组，用来保存所有选项
	type CascaderLevel = {
		id: number; // 唯一标识，用于each的key
		options: Option[]; // 该层级的选项数组
	};
	let optionsCantainer: CascaderLevel[] = [];
	let selectOptinIndex: number[] = [];
	let triggerRects: Array<{
		top: number;
		left: number;
		bottom: number;
		right: number;
		width: number;
		height: number;
	}> = [];
	
	// 重新定位标志，用于触发 PopoverSlot 重新计算位置
	let repositionFlag = 0;
	
	const handleMouseEnter = (option: Option, parentIndex: number, index: number) => {
		return async (e: MouseEvent) => {
			// 获取当前鼠标进入的菜单项位置
			const targetElement = e.currentTarget as HTMLElement;
			const itemRect = targetElement.getBoundingClientRect();
			
			// 计算子菜单的触发位置（基于当前菜单项）
			const newTriggerRect = {
				top: itemRect.top,
				left: itemRect.right,
				bottom: itemRect.bottom,
				right: itemRect.right,
				width: itemRect.width,
				height: itemRect.height
			};
			
			// 保存触发位置
			triggerRects[parentIndex] = newTriggerRect;
			
			// 计算垂直偏移（基于当前索引和滚动位置）
			const scrollElement =
				popoverSlotRefs[parentIndex]?.getElementsByClassName('scroll-container')[0];
			let scrollTop = 0;
			if (scrollElement) {
				scrollTop = scrollElement.scrollTop;
			}
						
			// 截取数组到当前级别并添加新的子级
			const remainingLevels = optionsCantainer.slice(0, parentIndex + 1);
			selectOptinIndex = selectOptinIndex.slice(0, parentIndex);
			if (option.children) {
				const newLevel: CascaderLevel = {
					id: generateLocalId(), // 每次新增层级都生成新ID！
					options: option.children
				};
				optionsCantainer = [...remainingLevels, newLevel];
				selectOptinIndex[parentIndex] = index;
			} else {
				optionsCantainer = remainingLevels;
			}
			
		};
	};
	const handleMouseClick = (option: Option) => {
		if (option && (!option.children || option.children.length === 0)) {
			onChange(option);
			onClose();
		}
	};
	const handleClickOutside = (event: MouseEvent) => {
		if (
			cascaderRef &&
			!cascaderRef.contains(event.target as Node) &&
			triggerRef &&
			!triggerRef.contains(event.target as Node)
		) {
			onClose();
		}
	};
	// 生成局部唯一 ID
	const generateLocalId = () => {
		localIdCounter++;
		return localIdCounter; // 如 local-1、local-2...
	};
	
	onMount(() => {
		portalContainer = ensurePortalContainer('popovers-container');
		if (options && triggerRef) {
			optionsCantainer = [
				{
					id: generateLocalId(), // 第一个层级的唯一ID（仅生成一次）
					options: options // 初始选项
				}
			];
			triggerRect = getElementRelativePos(triggerRef);
		}
		document.addEventListener('click', handleClickOutside);
		return () => {
			document.removeEventListener('click', handleClickOutside);
		};
	});
</script>

<Portal target={portalContainer}>
	<div class="cascader-container" bind:this={cascaderRef}>
		{#each optionsCantainer as level, parentIndex (level.id)}
			<PopoverSlot
				{placement}
				triggerRect={parentIndex === 0 ? triggerRect : triggerRects[parentIndex - 1]}							
				bind:popoverRef={popoverSlotRefs[parentIndex]}
				{repositionFlag}
			>
				<Scrollbar>
					{#each level.options as option, index (index)}
						<div
							class="cascader-item hover-bg"
							class:isActive={index == selectOptinIndex[parentIndex]}
							on:mouseenter={handleMouseEnter(option, parentIndex, index)}
							role="menuitem"
							tabindex="0"
							on:click={() => handleMouseClick(option)}
							on:keydown={() => {}}
						>
							<div class="cascader-item-option">{option[label]}</div>
							{#if option.children}
								<div class="cascader-item-expand">&gt;</div>
							{/if}
						</div>
					{/each}
				</Scrollbar>
			</PopoverSlot>
		{/each}
	</div>
</Portal>

<style scoped lang="scss">
	.cascader-container {
		position: absolute;
		display: flex;
		pointer-events: auto;
		align-items: flex-start; // 关键：子元素高度由自身内容决定，不拉伸
		// font-size: 14px;
	}
	.cascader-item {
		display: flex;
		flex-direction: row;
		justify-content: space-between;
		line-height: 32px;
		height: 32px;
		border-radius: var(--border-radius);
		cursor: pointer;
	}
	.cascader-item-option {
		margin-left: 10px;
	}
	.cascader-item-expand {
		margin-right: 10px;
		font-family: cursive;
	}
</style>